#include "db/segmentdataparser.hxx"
#include "dbt.hxx"
#include <assert.h>

void testassert(Dbt& dbt, std::string& str) {

    assert(dbt.getDatalen() == str.size());
    assert(memcmp(dbt.data(), str.data(), str.size()) == 0);
}

void func1() {
    
    //test serializeDbt
    //has no buffer
    std::string key("123"), value("1yyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
    std::string result = SegmentDataParser::serialize(key, value);
    Dbt keydbt(key), valuedbt(value), dbtresult1, dbtresult2;
    Dbt dbtresult = SegmentDataParser::serializeDbt(keydbt, valuedbt, dbtresult1);
    testassert(dbtresult, result); assert(dbtresult.getFlag() == DBT_MALLOC);
    assert(dbtresult.data() != dbtresult1.data());

    //has enough buffer
    char* buf = new char[256];
    dbtresult2.setBuffer(buf, 256, 0, DBT_MALLOC);
    dbtresult = SegmentDataParser::serializeDbt(keydbt, valuedbt, dbtresult2);
    testassert(dbtresult, result);
    testassert(dbtresult2, result); 
    assert(dbtresult.getFlag() == DBT_MALLOC);
}

void func2() {

    //test serializeDbtFromDbt

    std::string key("123"), value("1yyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
    std::string result = SegmentDataParser::serialize(key, value);
    Dbt keydbt(key), valuedbt(value), dbtresult1;
    Dbt dbtresult = SegmentDataParser::serializeDbt(keydbt, valuedbt, dbtresult1);
    
    //has no enough buffer
    std::string key1("abc123"), value1("1YYYYYYYYYYYYYYYYYYYYYYYYYYY");
    Dbt keydbt1(key1), valuedbt1(value1);

    result = SegmentDataParser::serialize(key1, value1, result);
    dbtresult1 = SegmentDataParser::serializeDbtFromDbt(keydbt1, valuedbt1, dbtresult);
    testassert(dbtresult1, result); assert(dbtresult1.getFlag() == DBT_MALLOC);
    assert(dbtresult.data() != dbtresult1.data());

    //has enough buffer space
    char* buf = new char[256];
    dbtresult.setBuffer(buf, 256, 0, DBT_MALLOC);
    SegmentDataParser::serializeDbt(keydbt, valuedbt, dbtresult);

    dbtresult1 = SegmentDataParser::serializeDbtFromDbt(keydbt1, valuedbt1, dbtresult);
    testassert(dbtresult1, result); assert(dbtresult1.getFlag() == DBT_MALLOC);
    assert(dbtresult.data() == dbtresult1.data());

    delete[] dbtresult1.data();
}

void func3() {
    
    //deletion
    std::string key("123"), value("1yyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
    Dbt keydbt(key), valuedbt(value); Dbt dbtresult;
    dbtresult = SegmentDataParser::serializeDbt(keydbt, valuedbt, dbtresult);
 
    std::string key1("abc123"), value1("1YYYYYYYYYYYYYYYYYYYYYYYYYYY");
    Dbt keydbt1(key1), valuedbt1(value1);
    
    Dbt dbtresult1 = SegmentDataParser::serializeDbtFromDbt(keydbt1, valuedbt1, dbtresult);
    
    SegmentDataParser::removeByKeyDbt(keydbt, dbtresult1);
    assert(keydbt1.getDatalen() == dbtresult1.getDatalen());
    assert(memcmp(keydbt1.data(), dbtresult1.data(), keydbt1.getDatalen()) == 0);
   
    SegmentDataParser::removeByKeyDbt(keydbt1, dbtresult1);
    assert(dbtresult1.getDatalen() == 0);
}


void func4() {
    
    std::string key("123"), value("1yyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
    Dbt keydbt(key), valuedbt(value); Dbt dbtresult;
    dbtresult = SegmentDataParser::serializeDbt(keydbt, valuedbt, dbtresult);

    std::string key1("abc123"), value1("1YYYYYYYYYYYYYYYYYYYYYYYYYYY");
    Dbt keydbt1(key1), valuedbt1(value1);

    Dbt dbtresult1 = SegmentDataParser::serializeDbtFromDbt(keydbt1, valuedbt1, dbtresult);

    Dbt v;
    SegmentDataParser::getValueByKeyDbt(keydbt, dbtresult1, v); 
    assert(memcmp(v.data(), valuedbt.data(), valuedbt.getDatalen()) == 0);
    assert(v.getFlag() == DBT_MALLOC);
}


int main() {

    func1();
    func2();
}

